/* eslint-disable no-case-declarations */
import path from 'node:path'
import fs from 'fs-extra'
import { getBrowser, logger, toMd, toPdf } from '@/utils'
import { evConfig } from '@/config'
import type { FileFormat } from '@/types'

const regex = /[\\/:\*\?"<>\|]/g
const windowsReservedNamesRegex = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])$/i // 匹配Windows保留名称的正则表达式
const storeDirs = path.join(evConfig.storeDirs ?? __dirname, 'books')
function getFileExtension(fileFormat: FileFormat): string {
  switch (fileFormat) {
    case 'pdf':
      return 'pdf'
    case 'md':
      return 'md'
    case 'html':
      return 'html'
    default:
      return 'txt'
  }
}
// 保存内容到文件
async function saveContentToFile(
  directoryPath: string,
  filename: string,
  content: string,
  fileType: FileFormat,
) {
  const fullFilename = `${filename}.${getFileExtension(fileType)}`
  const fileExists = await fs.pathExists(fullFilename)

  if (fileExists) {
    const existingContent = await fs.readFile(fullFilename, 'utf-8')
    if (existingContent.trim().length > 0) {
      logger.info(`文件${fullFilename}已存在且内容不为空，跳过保存`)
      return
    }
  }

  const removeStyleContent = removeStyleTags(content)

  try {
    switch (fileType) {
      case 'pdf':
        const pdf = await toPdf(removeStyleContent)
        await fs.writeFile(`${fullFilename}`, pdf)
        break
      case 'md':
        const md = await toMd(removeStyleContent)
        await fs.writeFile(`${fullFilename}`, md)
        break
      case 'html':
        await fs.writeFile(`${fullFilename}`, removeStyleContent)
        break
      default:
        logger.warn(`不支持的文件类型: ${fileType}`)
        break
    }

    // logger.info(`保存小册${title}章节到本地成功`)
    logger.info(`保存文件${fullFilename}到本地成功`)
  } catch (e) {
    logger.error(`保存文件${fullFilename}到本地失败`)
  }
}

// 保存章节内容到文件
async function saveSectionToFile(
  directoryPath: string,
  title: string,
  content: string,
  fileType: FileFormat,
) {
  const filename = path.join(directoryPath, `${title}`)
  await saveContentToFile(directoryPath, filename, content, fileType)
}

// 移除样式标签
function removeStyleTags(markdown: string): string {
  const styleTagRegex = /<style[^>]*>[\s\S]*?<\/style>/g
  return markdown.replace(styleTagRegex, '')
}

async function addBookLinkToReadme(bookLink: string, dir: string) {
  try {
    // Check if README.md exists, if not, create it
    if (!fs.existsSync(dir)) {
      let tpl = ''
      if (!dir.endsWith('\\books\\README.md')) {
        tpl = `## 简介 \n- <a href="./intro">小册介绍</a>\n### 目录\n`
      } else {
        tpl = `## 本小册由 <a href="https://github.com/h7ml/LagouSpecialSpider.git">LagouSpecialSpider</a>爬取 项目主页 <a href="https://h7ml.github.io/LagouSpecialSpider">h7ml.github.io/LagouSpecialSpider</a> \n### 小册总览\n`
      }
      await fs.promises.writeFile(dir, tpl)
    }

    const readmeContent = await fs.promises.readFile(dir, 'utf-8')
    if (!readmeContent.includes(bookLink)) {
      await fs.promises.appendFile(dir, `\n${bookLink}`)
    }
  } catch (error) {
    console.error('Error:', error)
  }
}

// 抓取图书
export async function spiderBooks(url: string) {
  logger.info(`启动 ${url} 任务 🚀`)
  const browser = await getBrowser()
  if (!browser) return

  try {
    const page = await browser.newPage()
    await page.goto(url)
    await page.setViewport({ width: 1920, height: 1080 })
    const anchorElement = await page.$('.conent-wrap .name')
    const title = await page.evaluate((elem) => elem.textContent?.trim(), anchorElement)
    if (!title) return
    logger.info(`即将保存小册${title}到本地`)
    const directoryPath = path.join(storeDirs, title)
    await fs.ensureDir(directoryPath)
    // 在storeDirs下的README.md中添加小册链接

    const bookLink = `- <a href="./${title}">${title}</a>\n`

    const readmePath = path.join(storeDirs, 'README.md')
    await addBookLinkToReadme(bookLink, readmePath)
    await page.click('.history-btn')
    await page.waitForTimeout(4000) // 等待页面加载
    const sectionListSelector = '.class-menu-block .class-level-one-detail'
    const menuPath = path.join(storeDirs, title, 'README.md')
    const sectionList = await page.$(sectionListSelector)
    if (sectionList) {
      const items = await page.$$(sectionListSelector)
      logger.info(`共${items.length}章节,开始写入目录`)
      for (const item of items) {
        const mtitle = await item.$eval('.text-wrap .content', (el) =>
          el.textContent?.replaceAll(' ', '').trim(),
        )
        const bookLink = `- <a href="./${mtitle}">${mtitle}</a>`
        await fs.appendFile(menuPath, `${bookLink}\n`)
        // 点击每个item
        await item.click()
        const container = await page.$('.main-container')
        const content = await page.evaluate((elem) => elem.innerHTML, container)
        await saveSectionToFile(directoryPath, mtitle, content, evConfig.filetype)
      }
    }
  } finally {
    await browser.close() // 关闭浏览器
  }
}
